const Package = require('../models/Package');
const DownloadStat = require('../models/DownloadStat');
const Tag = require('../models/Tag');
const PackageTag = require('../models/PackageTag');
const { Op } = require('sequelize');

class PackageService {
  // 获取包列表
  async getPackages({ page = 1, limit = 20, sortBy = 'downloads', sortOrder = 'desc', keyword = '', tagId = '' }) {
    try {
      const offset = (parseInt(page) - 1) * parseInt(limit);
      
      const where = {};
      
      if (keyword) {
        where[Op.or] = [
          { name: { [Op.like]: `%${keyword}%` } },
          { description: { [Op.like]: `%${keyword}%` } },
          { description_zh: { [Op.like]: `%${keyword}%` } }
        ];
      }
      
      let queryOptions = {
        where,
        order: [[sortBy, sortOrder]],
        limit: parseInt(limit),
        offset,
        include: [
          { model: Tag, as: 'tags', through: { attributes: [] } }
        ]
      };
      
      // 如果有标签筛选
      if (tagId) {
        const packagesWithTag = await PackageTag.findAll({
          where: { tag_id: parseInt(tagId) },
          attributes: ['package_id']
        });
        const packageIds = packagesWithTag.map(pt => pt.package_id);
        if (packageIds.length > 0) {
          queryOptions.where.id = { [Op.in]: packageIds };
        } else {
          // 如果没有找到相关包，返回空结果
          return {
            total: 0,
            pages: 0,
            currentPage: parseInt(page),
            packages: []
          };
        }
      }
      
      const { count, rows } = await Package.findAndCountAll(queryOptions);
      
      return {
        total: count,
        pages: Math.ceil(count / limit),
        currentPage: parseInt(page),
        packages: rows
      };
    } catch (error) {
      console.error('获取包列表失败:', error);
      // 返回空结果而不是抛出错误
      return {
        total: 0,
        pages: 0,
        currentPage: parseInt(page) || 1,
        packages: []
      };
    }
  }

  // 获取包详情
  async getPackageDetail(name) {
    try {
      const packageInfo = await Package.findOne({
        where: { name },
        include: [
          { model: Tag, as: 'tags', through: { attributes: [] } },
          {
            model: DownloadStat,
            as: 'download_stats',
            limit: 30,
            order: [['date', 'desc']]
          }
        ]
      });
      
      if (!packageInfo) {
        throw new Error('包不存在');
      }
      
      return packageInfo;
    } catch (error) {
      console.error('获取包详情失败:', error);
      throw error;
    }
  }

  // 搜索包
  async searchPackages(keyword, limit = 10) {
    try {
      if (!keyword) {
        return [];
      }
      
      const packages = await Package.findAll({
        where: {
          [Op.or]: [
            { name: { [Op.like]: `%${keyword}%` } },
            { description_zh: { [Op.like]: `%${keyword}%` } }
          ]
        },
        limit: parseInt(limit),
        attributes: ['id', 'name', 'description_zh']
      });
      
      return packages;
    } catch (error) {
      console.error('搜索包失败:', error);
      throw new Error('搜索包失败');
    }
  }

  // 获取热门包
  async getPopularPackages(limit = 20) {
    try {
      const packages = await Package.findAll({
        where: { is_popular: true },
        order: [['downloads', 'desc']],
        limit,
        include: [{ model: Tag, as: 'tags', through: { attributes: [] } }]
      });
      
      return packages;
    } catch (error) {
      console.error('获取热门包失败:', error);
      throw new Error('获取热门包失败');
    }
  }

  // 获取包的下载趋势
  async getDownloadTrend(packageId, days = 30) {
    try {
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - parseInt(days));
      
      const stats = await DownloadStat.findAll({
        where: {
          package_id: packageId,
          date: {
            [Op.between]: [startDate, endDate]
          }
        },
        order: [['date', 'asc']]
      });
      
      return stats;
    } catch (error) {
      console.error('获取下载趋势失败:', error);
      throw new Error('获取下载趋势失败');
    }
  }

  // 获取总排行榜
  async getLeaderboard(limit = 100) {
    try {
      const packages = await Package.findAll({
        order: [['downloads', 'desc']],
        limit,
        attributes: ['id', 'name', 'description_zh', 'downloads', 'score']
      });
      
      return packages;
    } catch (error) {
      console.error('获取总排行榜失败:', error);
      throw new Error('获取总排行榜失败');
    }
  }

  // 根据ID获取包详情
  async getPackageDetailById(id) {
    try {
      const packageInfo = await Package.findByPk(id, {
        include: [
          { model: Tag, as: 'tags', through: { attributes: [] } },
          {
            model: DownloadStat,
            as: 'download_stats',
            limit: 30,
            order: [['date', 'desc']]
          }
        ]
      });
      
      if (!packageInfo) {
        throw new Error('包不存在');
      }
      
      return packageInfo;
    } catch (error) {
      console.error('获取包详情失败:', error);
      throw error;
    }
  }

  // 创建包
  async createPackage(packageData) {
    try {
      const { tags, ...packageInfo } = packageData;
      
      const newPackage = await Package.create(packageInfo);
      
      // 处理标签关联
      if (tags && tags.length > 0) {
        for (const tagId of tags) {
          await PackageTag.create({
            package_id: newPackage.id,
            tag_id: tagId
          });
        }
      }
      
      return await this.getPackageDetailById(newPackage.id);
    } catch (error) {
      console.error('创建包失败:', error);
      throw new Error('创建包失败');
    }
  }

  // 更新包
  async updatePackage(id, packageData) {
    try {
      const { tags, ...packageInfo } = packageData;
      
      const existingPackage = await Package.findByPk(id);
      if (!existingPackage) {
        throw new Error('包不存在');
      }
      
      await existingPackage.update(packageInfo);
      
      // 更新标签关联
      if (tags !== undefined) {
        // 删除现有关联
        await PackageTag.destroy({ where: { package_id: id } });
        
        // 创建新关联
        if (tags.length > 0) {
          for (const tagId of tags) {
            await PackageTag.create({
              package_id: id,
              tag_id: tagId
            });
          }
        }
      }
      
      return await this.getPackageDetailById(id);
    } catch (error) {
      console.error('更新包失败:', error);
      throw error;
    }
  }

  // 删除包
  async deletePackage(id) {
    try {
      const existingPackage = await Package.findByPk(id);
      if (!existingPackage) {
        throw new Error('包不存在');
      }
      
      // 删除相关数据
      await PackageTag.destroy({ where: { package_id: id } });
      await DownloadStat.destroy({ where: { package_id: id } });
      
      await existingPackage.destroy();
      
      return { message: '删除成功' };
    } catch (error) {
      console.error('删除包失败:', error);
      throw error;
    }
  }

  // 评分更新
  async updateScore(packageId, score) {
    try {
      const packageInfo = await Package.findByPk(packageId);
      
      if (!packageInfo) {
        throw new Error('包不存在');
      }
      
      packageInfo.score = score;
      await packageInfo.save();
      
      return packageInfo;
    } catch (error) {
      console.error('更新评分失败:', error);
      throw new Error('更新评分失败');
    }
  }
}

module.exports = new PackageService();